home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
051-075
/
055
/
vt100
/
remote.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
10KB
|
388 lines
/****************************************************
* vt100 emulator - remote character interpretation
*
* v2.6 870227 DBW - bug fixes for all the stuff in v2.5
* v2.5 870214 DBW - more additions (see readme file)
* v2.4 861214 DBW - lots of fixes/additions (see readme file)
* v2.3 861101 DBW - minor bug fixes
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860803 DRB - Rewrote the control sequence parser
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
****************************************************/
#include "vt100.h"
static int p[10];
static int numpar;
static char escseq[40];
/************************************************
* function to handle remote characters
*************************************************/
void doremote(c)
char c;
{
if (c == 24) { inesc = 0; inctrl = 0; return; }
if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
if (inctrl >= 0 && c >= ' ') { doctrl(c); return; }
if (c == 10 || c == 11 || c == 12) {
if (nlmode) doindex('E'); else doindex('D');
return;
}
if (c == 13) {
if (!nlmode) emit(c);
return;
}
if (c == 15) { alt = 0; return; }
if (c == 14) { alt = 1; return; }
if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
emit(c);
}
void doesc(c)
char c;
{
if (inesc < 0) { inesc = 0; return; }
if (c == 27 || c == 24) { inesc = -1; return; }
if (c < ' ' || c == 127) return; /* Ignore control chars */
/* Collect intermediates */
if (c < '0') {escseq[inesc++] = c; return; }
/* by process of elimination, we have a final character.
Put it in the buffer, and dispatch on the first character
in the buffer */
escseq[inesc] = c;
inesc = -1; /* No longer collecting a sequence */
switch (escseq[0]) /* Dispatch on the first received */
{
case '[': /* Control sequence introducer */
numpar = 0; /* No parameters yet */
private = 0; /* Not a private sequence (yet?) */
badseq = 0; /* Good until proven bad */
p[0] = p[1] = 0; /* But default the first parameter */
inctrl = 0; /* We are in a control sequence */
return; /* All done for now ... */
case 'D': case 'E': case 'M': /* Some kind of index */
doindex (c); /* Do the index */
return; /* Return */
case '7': /* Save cursor position */
savx = x; savy = y; savmode = curmode; savalt = alt;
sa[0] = a[0]; sa[1] = a[1];
return;
case '8': /* Restore cursor position */
x = savx; y = savy; alt = savalt; curmode = savmode;
a[0] = sa[0]; a[1] = sa[1];
return;
case 'c': /* Reset */
top = MINY; bot = MAXY; savx = MINX; savy = MINY;
curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
inesc = -1;
a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
redoutil();
emit(12);
return;
case '(': /* Change character set */
if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
return;
case ')': /* Change the other character set */
if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
return;
case '=': /* set keypad application mode */
p_keyapp = 1;
redoutil();
return;
case '>': /* reset application mode */
p_keyapp = 0;
redoutil();
return;
case 'Z':
sendchar(27); sendstring("[?1;7c"); return;
/* If we didn't match anything, we can just return, happy in the
knowledge that we've at least eaten the whole sequence */
} /* End of switch */
return;
}
void doctrl(c)
char c;
{
int i;
if (c == 27 || c == 24) { inctrl = -1; return; }
if (c < ' ' || c == 127) return; /* Ignore control chars */
/* First, look for some parameter characters. If the very first
parameter character isn't a digit, then we have a
private sequence */
if (c >= '0' && c < '@')
{
/* can't have parameters after intermediates */
if (inctrl > 0) {badseq++ ; return; }
switch (c)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
p[numpar] = p[numpar] * 10 + (c - '0');
return;
case ';':
p[++numpar] = 0; /* Start a new parameter */
return;
case '<': case '=': case '>': case '?': /* Can only mean private */
/* Only allowed BEFORE parameters */
if (inctrl == 0) private = c;
return;
/* if we come here, it's a bad sequence */
}
badseq++; /* Flag the bad sequence */
}
if (c < '0') /* Intermediate character */
{
escseq[inctrl++] = c; /* Save the intermediate character */
return;
}
/* if we get here, we have the final character. Put it in the
escape sequence buffer, then dispatch the control sequence */
numpar++; /* Reflect the real number of parameters */
escseq[inctrl++] = c; /* Store the final character */
escseq[inctrl] = '\000'; /* Tie off the buffer */
inctrl = -1; /* End of the control sequence scan */
/* Don't know how to do most private sequences right now,
so just punt them */
if ((private != 0 && private != '?') || badseq != 0) return;
if (private == '?' && escseq[0] != 'h' &&
escseq[0] != 'l') return;
switch (escseq[0]) /* Dispatch on first intermediate or final */
{
case 'A': if (p[0]<=0) p[0] = 1;
y -= 8*p[0]; if (y<top) y = top; return;
case 'B': if (p[0]<=0) p[0] = 1;
y += 8*p[0]; if (y>bot) y = bot; return;
case 'C': if (p[0]<=0) p[0] = 1;
x += 8*p[0]; if (x>MAXX) x = MAXX; return;
case 'D': if (p[0]<=0) p[0] = 1;
x -= 8*p[0]; if (x<MINX) x = MINX; return;
case 'H': case 'f': /* Cursor position */
if (p[0] <= 0) p[0] = 1;
if (p[1] <= 0) p[1] = 1;
y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX;
if (y > MAXY) y = MAXY;
if (x > MAXX) x = MAXX;
if (y < MINY) y = MINY;
if (x < MINX) x = MINX;
return;
case 'L': /* ANSI insert line */
case 'M': /* ANSI delete line */
if (p[0] <= 0) p[0] = 1;
ScrollRaster(mywindow->RPort,0L,
(long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
(long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
return;
case 'r': /* Set scroll region */
if (p[0] <= 0) p[0] = 1;
if (p[1] <= 0) p[1] = p_lines;
top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY;
if (top < MINY) top = MINY;
if (bot > MAXY) bot = MAXY;
if (top > bot) { top = MINY; bot = MAXY; }
x = MINX; y = MINY;
return;
case 'm': /* Set graphic rendition */
for (i=0;i<numpar;i++) {
if (p[i] < 0) p[i] = 0;
switch (p[i]) {
case 0:
curmode = FS_NORMAL;
break;
case 1:
curmode |= FSF_BOLD;
break;
case 4:
curmode |= FSF_UNDERLINED;
break;
case 5:
curmode |= FSF_ITALIC;
break;
default:
curmode |= FSF_REVERSE;
break;
}
}
return;
case 'K': /* Erase in line */
doerase();
return;
case 'J': /* Erase in display */
if (p[0] < 0) p[0] = 0;
SetAPen(mywindow->RPort,0L);
if (p[0] == 0) {
if (y < MAXY) RectFill(mywindow->RPort,
(long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
}
else if (p[0] == 1) {
if (y > MINY) RectFill(mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
}
else RectFill(mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
SetAPen(mywindow->RPort,1L);
doerase(); return;
case 'h': /* Set parameter */
if (private == 0 && p[0] == 20) nlmode = 1;
else if (private == '?') {
if (p[0] == 7) p_wrap = 1;
else if (p[0] == 1) p_curapp = 1;
redoutil();
}
return;
case 'l': /* Reset parameter */
if (private == 0 && p[0] == 20) nlmode = 0;
else if (private == '?') {
if (p[0] == 7) p_wrap = 0;
else if (p[0] == 1) p_curapp = 0;
redoutil();
}
return;
case 'x':
sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
case 'n':
if (p[0] == 6) {
sendchar(27);
sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
sendstring(escseq); return;
}
sendchar(27); sendstring("[0n"); return;
case 'c':
sendchar(27); sendstring("[?1;7c"); return;
}
/* Don't know how to do this one, so punt it */
}
void doindex(c)
char c;
{
if (c != 'M') {
if (c == 'E') x = MINX;
if (y > bot) if (y < MAXY) y += 8;
if (y == bot)
ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y < bot) y += 8;
}
else {
if (y < top) if (y > MINY) y -= 8;
if (y == top)
ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y > top) y -= 8;
}
return;
}
doalt(c)
char c;
{
int oldx,newx;
inesc = -1;
oldx = x; emit(' '); newx = x;
x = oldx;
SetAPen(mywindow->RPort,1L);
switch (c) {
case 'a':
doline(0,-6,8,1);
break;
case 'j':
case 'm':
case 'v': doline(4,-6,4,-2);
if (c=='j') doline(0,-2,4,-2);
else if (c=='m') doline(4,-2,8,-2);
else doline(0,-2,8,-2);
break;
case 'k':
case 'l':
case 'w': doline(4,-2,4,1);
if (c=='k') doline(0,-2,4,-2);
else if (c=='l') doline(4,-2,8,-2);
else doline(0,-2,8,-2);
break;
case 'n':
case 'q': doline(0,-2,8,-2);
if (c=='n') doline(4,-6,4,2);
break;
case 't':
case 'u':
case 'x': doline(4,-6,4,1);
if (c=='t') doline(4,-2,8,-2);
else if (c=='u') doline(0,-2,4,-2);
break;
}
x = newx;
}
doline(x1,y1,x2,y2) {
RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
(long)(x+x2),(long)(y+y2));
}
void doerase()
{
if (p[0] < 0) p[0] = 0;
SetAPen(mywindow->RPort,0L);
if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
(long)(MAXX+7),(long)(y+1));
else if (p[0] == 1) RectFill(mywindow->RPort,
(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
else RectFill(mywindow->RPort,
(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
SetAPen(mywindow->RPort,1L);
return;
}